package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;

import exception.NameTakenException;
import exception.UserNotConnectedException;

import server.IServer;
/**
 * Class ConsoleClient
 * Interface Console for each client
 * @author Thibault MERLE & Moritz FISCHER
 *
 */
public class ConsoleClient {
	private Client client;
	private IServer server;
	private BufferedReader input;
	public static final String PROMPT = "# ";
	
	/**
	 * Creates an instance ConsoleClient
	 * @param client : interface given to the server.
	 */
	public ConsoleClient(IClient client) {
		this.input = new BufferedReader(new InputStreamReader(System.in));
		this.client = (Client) client;
		this.server = this.client.getServer();
	}
	
	/**
	 * Functions to read a line into the console
	 * @return a string which is the line typed.
	 */
	private String readLine() {
		String line = "";
		try { line =  input.readLine().trim(); } 
		catch (IOException e) {
			System.out.println("Error readLine");
		}
		return line;
	}
	
	/**
	 * Function to log on the server.
	 */
	public int logOn() {
		System.out.print("# Username = ");
		String username = readLine();
		client.setUsername(username);
		try {
			server.logOn((IClient) client, username);
			System.out.println("You are connected to the server.");
			return 0;
		} catch (RemoteException e) {
			System.out.println("Server unreachable...");
			return -1;
		} catch (NameTakenException e) {
			System.out.println("Name already used by another user.\nTry another pseudo:");
			return -1;
		}
		
	}

	/**
	 * After to be logged on the server. We use this function
	 * to use all features of our client.
	 */
	public void run () {
		String command = "";
		while(true) {
			System.out.print(PROMPT);
			command = "";
			command = readLine();
			
			if(command.equals("who")) {
				// # who
				try {
					System.out.println("You are connected to:");
					ArrayList<String> listConnectedUsers  = (ArrayList<String>) server.getClientNames();
					listConnectedUsers.remove(client.getUsername());
					if(listConnectedUsers.size() == 0) {
						System.out.println("No other user connected");
					} else {
						for(String user : listConnectedUsers) {
							System.out.println("- " + user);
						}
					}
				} catch (RemoteException e) {
					System.out.println("Server is unreachable...\n" +
							"According to your list of friends, people connected are:");
					HashMap<String, IClient> friends = client.getListFriends();
					for(String friend: friends.keySet()) {
						System.out.println("- " + friend);
					}
				}
			} else if(command.equals("msg")) {
				// # msg
				String destination = "";
				IClient clientDest = null;
				try {
					System.out.println("To whom ? (all or username)");
					destination = input.readLine();
				} catch (IOException e) {
					System.err.println("Error when typing receiver");
				}
				if(destination.equals("all")) {
					// Send a message to everybody
					System.out.println("What's the message ?");
					String message = readLine();
					try {
						server.sendMessage(client.getUsername(), message);
						System.out.println("# " + message + "has been sent to everybody.");
					} catch (RemoteException e) {
						System.out.println("Sending message failed");
					}
				} else {
					// Check in the local list
					HashMap<String, IClient> friends = client.getListFriends();
					for(String user: friends.keySet()) {
						if(user.equals(destination)) {
							clientDest = friends.get(user);
						}
					}
					// Check on the server
					if(clientDest == null) {
						try {
							clientDest = server.getClient(destination);
							client.addKnownIClient(destination, clientDest);
						} catch(UserNotConnectedException e) { 
							System.out.println("No client with this name!");
							continue;
						} catch (RemoteException e) {
							System.out.println("Error getClient Remote function");
							continue;
						}
					}
					// Send the message
					System.out.println("What's the message ?");
					String message = readLine();
					try {
						clientDest.sendPrivateMessage(client.getUsername(), message);
						System.out.println("# " + message + " has been sent to "+ destination + ".");
					} catch (RemoteException e) {
						System.out.println("Sending the message failed");
					}
				}
			} else if(command.equals("quit")) {
				try {
					server.logOff(client.getUsername());
					input.close();
					System.exit(0);
				} catch (RemoteException e) {
					System.out.println("Error logoff : Server disconnected or unreachable maybe...");
					// Case server disconnected: We call all the client to tell them
					HashMap<String, IClient> listFriends = client.getListFriends();
					for(String friend: listFriends.keySet()) {
						try {
							listFriends.get(friend).notifyLeave(client.getUsername());
						} catch (RemoteException e1) {
							System.out.println("Notification not transmitted.");
						}
					}
					System.exit(0);
				} catch (IOException e) {
					e.printStackTrace();
					System.exit(0);
				} catch (UserNotConnectedException e) {
					System.out.println("User already disconnected.");
					System.exit(0);
				}
			
			} else if(command.equals("help")) {
				String help = "- who: to know who is connected on the server.\n"
					+ "- msg: to send a message. If you type the keyword \"all\" for the destination,\n"
					+ "the message will be sent to everybody. In the other case type the name of a \n"
					+ "connected user.\n"
					+ "- quit: to quit properly the chat.";
				System.out.println(help);
			} else {
			
				System.out.println("Command Unknown: help to see all commands");
			}
			
		}
		
		
	}
}
